
// Generated by Interface Builder
// Modified by Eric Tremblay May 16, 1992
// Revised on January 24, 1993

#import "Amort.h"
#include <math.h>

// Gobal Variables

	const char *fileName; // The fileName for the SaveFile method
	int saveOK;           // Used by the SavePanel in the getName method
	char buffer[800];     // Text buffer

@implementation Amort

// AWAKEFROMNIB
// This is one of the last methods executed after the nib file is loaded.
// This is the BEST way I know how to initialize an object and jump into
// a method after the nib file was loaded, because you are all the methods
// and variables needed can be used. (Unlike init which is not compeletly
// ready when that message is sent
- awakeFromNib
{
  	long time(), tmpTime;
	struct tm *tm, *localtime();
	
	tmpTime = time(0);
	tm = localtime( &tmpTime );
	sysMonth = (tm->tm_mon+1);
	sysYear = (1900+tm->tm_year);
        mbeg = sysMonth; // This will set the default for the month of January
	[NXApp activateSelf:YES]; //activate the application 
	
	return self; //normal return
}



// CALC
- Calc:sender
// This method generates an amortization table and prints the result
// in the various fields and in the ScrollView (Only outputs to the Screen)
{

// Declare the variables
        
	char pmtString[20]; // (payment) pmt float value in a string
	char icString[20];  // (Interest chaged) ic float value in a string
	char fvString[20];  // (Total cost) fv float value in a string
	float amt;          // Input for Principal
	float rate;         // Input for Interest Rate	
	float ic;           // Interest Payed
	float pmt;          // Payment
	float fv;           // Total Cost
	int term;         // # of months for the term
	float r, temp;
	float exp, prin, x, y, yrint = 0;
	int mnbr;
	int month, i, k, yr=1;
        int dummy;          // Used by the AlertPanel
	
		   
	 // Gets the value from the Principle field
         amt = [Principal floatValue];

// If the value of the loan is over 49000$, it will
// display this alert panel	
	if (amt > 49000) {
dummy = NXRunAlertPanel("Are you serious?","Do you really want to spend that much money?","Think about it!",NULL, NULL);
                                   }

// Gets the value from the Years and Months field in the Term box
// Then multiplies Years by 12 and adds the value of Months to the term int
	 term = ([Years floatValue]*12)+[Months floatValue];
	 
	 // Gets the value from the Interest rate % field
	 rate = [InterestRate floatValue];


//  Computes payment and future value

	r = rate/100.0;
	x = 1.0 + r/12.0;
	y = term;
	temp = (1.0 / pow(x,y));
	pmt = (amt*r/12.0) / (1-temp);
	k = term;
	fv = pmt*k;
	ic = fv - amt;
 
	// Clears the AmortDisplay scrollView
	[[AmortDisplay docView] setText:""];
		 
        // Places the values in thier proper field on the screen
	
	sprintf( pmtString, "$%.2f", pmt); // Convert float to a string
	[Payment setStringValue:pmtString];// Result for Payment
	
	sprintf( icString, "$%.2f", ic); // Convert float to a string
	[InterestPayed setStringValue:icString];// Result for Interest Payed
	
	sprintf( fvString, "$%.2f", fv); // Convert float to a string
	[TotalCost setStringValue:fvString]; // Result for Total Cost

        // Header in the AmortDisplay scrollView
	sprintf(buffer,"\n     *** Amortize ***\n");
	[self appendText:sender];
        sprintf(buffer," The Amortization tool.\n\n");
        [self appendText:sender];
	sprintf(buffer,"Principal:  $%.2f\n", amt);
	[self appendText:sender];
	sprintf(buffer,"Interest rate:  %3.2f%%\n", rate);
	[self appendText:sender];
	sprintf(buffer,"Term of loan in months:  %d\n", term);
	[self appendText:sender];
	sprintf(buffer,"Monthly payment:  $%.2f\n", pmt);
	[self appendText:sender];
	 sprintf(buffer,"Total interest charged:  $%.2f\n", ic);
	 [self appendText:sender];
	 sprintf(buffer,"Total cost of loan:  $%.2f\n", fv);
	 [self appendText:sender];
	 sprintf(buffer,"\nMonth\tInterest\t\tPrincipal\t\tBalance\n");	 [self appendText:sender];

	
// Start of loop to print amortization schedule
	   
	      mnbr=mbeg;
	      for (i=1; i<=k; i++) {
	      month = i;
	      exp = amt*(r/12.0);
	      yrint=yrint+exp;
	      prin = pmt-exp;
	      amt = amt-prin;
	      mnbr++;
sprintf(buffer,"%d\t %.2f\t\t %.2f\t\t %.2f\n",mnbr-1, exp, prin, amt);    
	      [self appendText:sender];
	      if (mnbr > 12 ) { 
	                               sprintf(buffer,"\t\tInterest paid for year %d is %.2f\n\n",yr,yrint); 
				        [self appendText:sender];
					 yr++;
	                                yrint=0;
	                                mnbr=1;
                                      }
               }
        
	      if (mnbr !=1 && mnbr != 13) {
				      sprintf(buffer,"\t\tInterest paid for year %d is %.2f\n\n",yr,yrint);
	                              [self appendText:sender];
	                             }

     return self; //normal return, end of Calc method
}

// JANUARY
- January:sender
// Assigns a value to mbeg for the Starting month
{
    mbeg = 1;
    return self;
}

// FEBRUARY
- February:sender
{
    mbeg = 2;
    return self;
}

// MARCH
- March:sender
{
    mbeg = 3;
    return self;
}

// APRIL
- April:sender
{
    mbeg = 4;
    return self;
}

// MAY
- May:sender
{
    mbeg = 5;
    return self;
}

// JUNE
- June:sender
{
    mbeg = 6;
    return self;
}

// JULY
- July:sender
{
    mbeg = 7;
    return self;
}

// AUGUST
- August:sender
{
    mbeg = 8;
    return self;
}

// SEPTEMBER
- September:sender
{
    mbeg = 9;
    return self;
}

// OCTOBER
- October:sender
{
    mbeg = 10;
    return self;
}

// NOVEMBER
- November:sender
{
    mbeg = 11;
    return self;
}

// DECEMBER
- December:sender
{
    mbeg = 12;
    return self;
}

// The two methods below getName and SaveFile are used by
// the save to a file option in Amortize. These methods are used only
// for the file to disk option

// SETFILENAME
- setFileName:(const char *)aFilename
{
   	if (filename) free(filename);
	filename = malloc(strlen(aFilename)+1);
 	strcpy(filename, aFilename);
	[AmortWindow setTitleAsFilename:aFilename];
	return self;
}

//SAVEAS
- SaveAs:sender
{
	id panel;
	const char *dir;
	char *file;

// Prompt user for file name and save to that file

	if (filename==0) {
	/* no filename; set up defaults */
	dir = NXHomeDirectory();
	file = (char *) [AmortWindow title];
                         }
else {
	file = rindex(filename, '/');
	if (file) {
	  dir = filename;
	  *file =0;
	  file++;
                  }
else {
	dir = filename;
	file = (char *) [AmortWindow title];
     }
     }

	panel = [SavePanel new];

	[panel setRequiredFileType: "amortize"];
	if ([panel runModalForDirectory: dir
                   file: file])  {
           [self setFileName: [panel filename] ];

    	   return [self SaveFile: sender];
                                 }
	return nil; // didn't save
}	


// SAVEFILE
- SaveFile:sender
// This method generates an amortization table and prints the result in the
// various fields on the screen and prints a file to the disk.
// This method method really does the same thing as the Calc method
// except it generates it's output to a file on the disk.
{

	int fd;
	NXStream *theStream;
	
	if (filename==0) return [self SaveAs: sender];
 	[AmortWindow setTitle: "Saving..."];

	fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
        if (fd<0) {
          NXRunAlertPanel(0, "Cannot save file: %s",0,0,0,strerror(errno));
          return self;
                  }	

	theStream = NXOpenFile(fd, NX_WRITEONLY);
	[[AmortDisplay docView] writeRichText:theStream];
	
	NXClose(theStream);
	close(fd);

	[AmortWindow setTitleAsFilename: filename];
	return self;
}

// APPENDTEXT
- appendText:sender
// This method appends a string called buffer to the end 
// of AmortDisplay scrollView
{
    	int HowLongIsTheText;
	
	document = [AmortDisplay docView];
        
	// Determines how many characters are in the 
        // AmortDisplay scrollView document
	HowLongIsTheText = [document textLength]; 
        
        // Selects and empty selection, which in fact places
        // the cursor at the end of the document.
	[document setSel:HowLongIsTheText:HowLongIsTheText];
        
	// Replaces the selection (in this case it is empty) 
        // with buffer text string.
	[document replaceSel:buffer]; 

	return self; //normal return
}
 
// PRINTTABLE
- PrintTable:sender
// This method will print the AmortDisplay to the printer
// Printing is rather simple; just send printPSCode: to the text view
// you wish to print. The print panel will automatically pop up and unless
// the user cancels the printout the text view will be printed.
{    
    [[AmortDisplay docView] printPSCode:self];
    return self;
 }
  

@end
